package jmine.tec.web.front.domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import jmine.tec.persist.annotation.Alias;
import jmine.tec.persist.annotation.Comment;
import jmine.tec.persist.annotation.Comments;
import jmine.tec.persist.annotation.Index;
import jmine.tec.persist.annotation.Indexes;
import jmine.tec.persist.annotation.UniqueConstraint;

import org.hibernate.validator.NotNull;

import bancosys.tec.component.Documentation;
import bancosys.tec.persist.bussobj.PersistableBusinessObject;
import bancosys.tec.persist.persister.annotation.NaturalKey;
import bancosys.tec.persist.persister.annotation.SystemId;

/**
 * A command type, dictates how to deal with the command.
 * 
 * @author lundberg
 */
@Entity
@Alias("BORQTP")
@Table(name = "BACK_OFFICE_REQUEST_TYPE")
@Documentation("ARMAZENA O TIPO DE REQUISICAO AO BACK OFFICE.")
@SequenceGenerator(sequenceName = "SEQ_BORQTP", name = "SEQ_BORQTP")
public class BackOfficeRequestType extends PersistableBusinessObject {

    private Long id;

    private String mnemonic;

    private String metadata;

    private Set<BackOfficeRequestProperty> properties = new HashSet<BackOfficeRequestProperty>();

    /**
     * @return the id
     */
    @Id
    @SystemId
    @GeneratedValue(generator = "SEQ_BORQTP")
    @Column(name = "COD_BACK_OFFICE_REQUEST_TYPE", nullable = false)
    @Documentation("CODIGO DO TIPO DE REQUISICAO")
    public Long getId() {
        return this.id;
    }

    /**
     * @return the mnemonic
     */
    @NotNull
    @NaturalKey
    @UniqueConstraint(suffix = "JT_0")
    @Column(name = "MNE", nullable = false)
    @Documentation("MNEMONICO DO TIPO DE REQUISICAO")
    public String getMnemonic() {
        return this.mnemonic;
    }

    /**
     * @return the metadata bean name
     */
    @NotNull
    @Column(name = "METADATA", nullable = false)
    @Documentation("IDENTIFICADOR DO CONJUNTO DE METADADOS ATRELADO AO TIPO")
    public String getMetadata() {
        return this.metadata;
    }

    /**
     * List of properties used by this type ordered by pk.
     * 
     * @return list of properties
     */
    public List<BackOfficeRequestProperty> properties() {
        List<BackOfficeRequestProperty> result = new ArrayList<BackOfficeRequestProperty>();
        result.addAll(this.getProperties());
        Collections.sort(result, new Comparator<BackOfficeRequestProperty>() {
            public int compare(BackOfficeRequestProperty o1, BackOfficeRequestProperty o2) {
                return o1.getId().compareTo(o2.getId());
            }
        });
        return result;
    }

    /**
     * @return the properties
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "ASSOC_REQUEST_TYPE_PROPERTY", joinColumns = @JoinColumn(name = "COD_BACK_OFFICE_REQUEST_TYPE", nullable = false), inverseJoinColumns = @JoinColumn(name = "COD_BACK_OFFICE_REQ_PROP", nullable = false))
    @UniqueConstraint(suffix = "JT_0", columns = { "COD_BACK_OFFICE_REQUEST_TYPE", "COD_BACK_OFFICE_REQ_PROP" })
    @Indexes({ @Index(suffix = "JT_0", columns = "COD_BACK_OFFICE_REQUEST_TYPE"),
            @Index(suffix = "JT_1", columns = "COD_BACK_OFFICE_REQ_PROP") })
    @Alias("ASRQTP")
    @Comments({
            @Comment(table = "ASSOC_REQUEST_TYPE_PROPERTY", value = "ASSOCIACAO ENTRE UM TIPO DE REQUISICAO E AS PROPRIEDADES UTILIZADAS POR SUAS REQUISICOES."),
            @Comment(table = "ASSOC_REQUEST_TYPE_PROPERTY", column = "COD_BACK_OFFICE_REQUEST_TYPE", value = "CODIGO DO TIPO DE REQUISICAO."),
            @Comment(table = "ASSOC_REQUEST_TYPE_PROPERTY", column = "COD_BACK_OFFICE_REQ_PROP", value = "CODIGO DA PROPRIEDADE DE REQUISICAO.") })
    protected Set<BackOfficeRequestProperty> getProperties() {
        return this.properties;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param mnemonic the mnemonic to set
     */
    public void setMnemonic(String mnemonic) {
        this.mnemonic = mnemonic;
    }

    /**
     * @param properties the properties to set
     */
    protected void setProperties(Set<BackOfficeRequestProperty> properties) {
        this.properties = properties;
    }

    /**
     * Adds a supported property
     * 
     * @param property property
     */
    public void addProperty(BackOfficeRequestProperty property) {
        this.properties.add(property);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return this.getMnemonic();
    }

    /**
     * Cleans all properties
     */
    public void clearProperties() {
        this.getProperties().clear();
    }

    /**
     * Removes a property
     * 
     * @param property property
     */
    public void removeProperty(BackOfficeRequestProperty property) {
        this.getProperties().remove(property);
    }

    /**
     * Adds all properties
     * 
     * @param properties2 properties2
     */
    public void addAllProperties(Set<BackOfficeRequestProperty> properties2) {
        this.getProperties().addAll(properties2);
    }

    /**
     * @param metadata the filterPanelFactory to set
     */
    public void setMetadata(String metadata) {
        this.metadata = metadata;
    }
}
